#include<iostream>
#include<string>
#include<unistd.h>
#include<sys/wait.h>
#include<sys/types.h>
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<assert.h>
using namespace std;


#define DELIM " \t"
#define LEFT "["
#define RIGHT "]"
#define LABLE "$"
#define LINE_SIZE 1024
#define ARGC_SIZE 32
#define EXIT_CODE 4

int quit = 0;
int LASTCODE = 0;
char *argv[ARGC_SIZE];
char commondline[LINE_SIZE];
char pwd[ARGC_SIZE];
char myenv[ARGC_SIZE];



//usr
const char *getusr()
{
    return getenv("USER");
}

//hostname 
const char* gethostname()
{
    return getenv("HOSTNAME");
}


//cwd 
void  getpwd()
{
   getcwd(pwd,sizeof(pwd));
}

void ineract(char* cline , int size)
{
    getpwd();
    printf(LEFT"%s@%s %s"RIGHT""LABLE" ",getusr(),gethostname(),pwd);
    
    char *s = fgets(cline ,size ,stdin);
    assert(s);
//    perror(s);
    (void)s;

    cline[strlen(cline)-1] = '\0';
}

//命令行解析
int AnalyzeCommandLine(char* cline)
{
    int i = 0;
    argv[i++] = strtok(cline,DELIM);
    while(argv[i++] = strtok(NULL,DELIM));
    
    return i-1;
}
//常规命令
void NormalExecl(char* _argv[])
{
    pid_t id = fork();
    if(id < 0)
    {
        perror("fork");
        return;
    }
    else if(id == 0)
    {
        execvp(_argv[0],argv);
        exit(EXIT_CODE);
   }
    else 
    {
        int status = 0;
        pid_t rid = waitpid(id ,&status,0);
        if(id) 
        {
            LASTCODE = WEXITSTATUS(status); 
        }
    }
}


//内建命令
int BuildExec(char* _argv[],int _argc)
{
    if(_argc == 2 && strcmp(_argv[0],"cd") == 0)
    {
        chdir(_argv[1]);
        getpwd();
         sprintf(getenv("PWD"),"%s",pwd);
        return 1;
    }
    else if(_argc == 2 && strcmp(_argv[0],"export") == 0)
    {
        strcpy(myenv ,_argv[1]);
        putenv(myenv);
        return 1;
    }
    else if(_argc ==2 && strcmp(_argv[0],"echo") == 0)
    {
        if(strcmp(_argv[1],"$?"))
        {
            printf("%d\n",LASTCODE);
            LASTCODE = 0;
        }
        else if (strcmp(_argv[1],"$"))
        {
            char* val = getenv(_argv[1]+1);
            printf("%s\n",val);
        }
        else 
        {
            printf("%s\n",_argv[1]);
        }
    }

    if(strcmp(_argv[0],"ls") == 0)
    {
        _argv[_argc++] = "--color";
        _argv[_argc] = NULL;
    }

    return 0;
}

int main()
{   


    while(!quit)
    {
        
         //命令行提示
        ineract(commondline,sizeof(commondline));
        //命令解析
        int argc = AnalyzeCommandLine(commondline); 
        //指令解析
        int n = BuildExec(argv,argc);
        if(!n) NormalExecl(argv);
    }

    return 0;

}
